﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Diagnostics;
namespace SmokinAces.Object_Classes.Objects
{
    public class Map_Tile : Game_Object, Draw_Object
    {
        //------this is information for the editor...
        static Type[] constructor_parameters = { typeof(int), typeof(int),typeof(Weather_Type),typeof(Enviornment_Type),typeof(Tile_Type), typeof(int[]), typeof(Main_Engine) };
        static object[] default_const_values = { 0, 0, Weather_Type.None, Enviornment_Type.Normal, Tile_Type.Grass, new int[4]{0,0,0,0}, null };
        //------------------------------------
        VertexPositionColorTexture[] vertices;
        VertexPositionColorTexture[] defaultvertices;
		int[] indecies;
        int[] Colors = new int [4];
        private int groundTexture;
        private Sort_Delegate m_Sort_Delegate;
        private Weather_Type _Tile_Weather = Weather_Type.None;
        public Weather_Type Tile_Weather
        {
            get { return _Tile_Weather; }
            set { _Tile_Weather = value; }
        }
        private Enviornment_Type _Tile_Enviornment = Enviornment_Type.Normal;
        public Enviornment_Type Tile_Enviornment
        {
            get { return _Tile_Enviornment; }
            set { _Tile_Enviornment = value; }
        }
        private Tile_Type _Tile_Texture = Tile_Type.Grass;
        public Tile_Type Tile_Texture
        {
            get { return _Tile_Texture; }
            set 
            { 
                _Tile_Texture = value;
                this.Bounding_Regions.Clear();
                switch (_Tile_Texture)
                {
                    case Tile_Type.Grass:
                        groundTexture = parent.register_texture("Grass_Texture.png");
                        break;
                    case Tile_Type.Sand:
                        groundTexture = parent.register_texture("Sand_Texture.png");
                        break;
                    case Tile_Type.Snow:
                        groundTexture = parent.register_texture("Snow_Texture.png");
                        break;
                    case Tile_Type.Swamp:
                        groundTexture = parent.register_texture("Swamp_Texture.png");
                        break;
                    case Tile_Type.Water:
                        groundTexture = parent.register_texture("Water_Texture.png");
                        this.Bounding_Regions.Add(GraphicBB);
                        break;
                    case Tile_Type.Dirt:
                        groundTexture = parent.register_texture("Dirt_Texture.png");
                        break;
                }
                defaultvertices[0].Color = Map_Colors.Get_Color(Tile_Texture, Colors[0]);
                defaultvertices[1].Color = Map_Colors.Get_Color(Tile_Texture, Colors[2]);
                defaultvertices[2].Color = Map_Colors.Get_Color(Tile_Texture, Colors[1]);
                defaultvertices[3].Color = Map_Colors.Get_Color(Tile_Texture, Colors[3]);
                //--- Dericks Code
                vertices = Util.ComplexMesh(defaultvertices, out indecies, 4, 4);
            }
        }
        public Map_Tile(XmlReader xmlReader, Main_Engine Parent)
        {
            xmlReader.Read();
            string sLeft = xmlReader.ReadElementString("Left");
            string sTop = xmlReader.ReadElementString("Top");
            string sColor0 = xmlReader.ReadElementString("Color0");
            string sColor1 = xmlReader.ReadElementString("Color1");
            string sColor2 = xmlReader.ReadElementString("Color2");
            string sColor3 = xmlReader.ReadElementString("Color3");
            string sTile_Weather = xmlReader.ReadElementString("Tile_Weather");
            string sTile_Enviornment = xmlReader.ReadElementString("Tile_Enviornment");
            string sTile_Texture = xmlReader.ReadElementString("Tile_Texture");
            //----------------Extract the Colors
            int[] tempArray = new int[4];
            tempArray[0] = Convert.ToInt32(sColor0);
            tempArray[1] = Convert.ToInt32(sColor1);
            tempArray[2] = Convert.ToInt32(sColor2);
            tempArray[3] = Convert.ToInt32(sColor3);
            //------------------------------------
            int left = Convert.ToInt32(sLeft);
            int top = Convert.ToInt32(sTop);
            Weather_Type wType = (Weather_Type)Enum.Parse(typeof(Weather_Type),sTile_Weather);
            Enviornment_Type eType = (Enviornment_Type)Enum.Parse(typeof(Enviornment_Type),sTile_Enviornment);
            Tile_Type tType = (Tile_Type)Enum.Parse(typeof(Tile_Type),sTile_Texture);

            Initialize(left, top, left + 64, top + 64, wType, eType, tType, tempArray, Parent);
        }

        public Map_Tile(int left, int top, Main_Engine parent)
        {
            int[] colors = new int[4];
            colors[0] = 0;
            colors[1] = 0;
            colors[2] = 0;
            colors[3] = 0;
            left = ((int)(left / 64)) * 64;
            top = ((int)(top / 64)) * 64;
            Initialize(left, top, left + 64, top + 64,Weather_Type.None,Enviornment_Type.Normal,Tile_Type.Grass, colors, parent);
        }
        public Map_Tile(int left, int top,Weather_Type weather, Enviornment_Type enviornment, Tile_Type texture, int[] color, Main_Engine parent)
        {
            left = ((int)(left / 64)) * 64;
            top = ((int)(top / 64)) * 64;
            Initialize(left, top, left + 64, top + 64,weather,enviornment,texture, color, parent);
        }

        private void Initialize(int left, int top, int right, int bottom,Weather_Type weather, Enviornment_Type enviornment, Tile_Type aTile_Texture, int[] color, Main_Engine parent)
        {
            Colors = color;
            GraphicBB = new BoundingBox(new Vector3(left, top, Util.MinZ), new Vector3(right, bottom, Util.MaxZ));
            this.parent = parent;
            const float zorder = 1.0f;
            const float cwidth = 256.0f;
            const float cheight= 192.0f;
            defaultvertices = new VertexPositionColorTexture[4];
            defaultvertices[0].Position = new Vector3(left, top, zorder);
            defaultvertices[0].TextureCoordinate = new Vector2(left / cwidth, top / cheight);
            defaultvertices[1].Position = new Vector3(left, bottom, zorder);
            defaultvertices[1].TextureCoordinate = new Vector2(left / cwidth, bottom / cheight);
            defaultvertices[2].Position = new Vector3(right, top, zorder);
            defaultvertices[2].TextureCoordinate = new Vector2(right / cwidth, top / cheight);
            defaultvertices[3].Position = new Vector3(right, bottom, zorder);
            defaultvertices[3].TextureCoordinate = new Vector2(right / cwidth, bottom / cheight);
            //---------------This adds the draw function to the appropriate layer
            //parent.add_Drawing_Object("Grass_Texture.png", Draw, Layers.Layer0);
            m_Sort_Delegate = new Sort_Delegate(((1024 - bottom) * 1024) + left , Draw);
            _Tile_Weather = weather;
            Tile_Texture = aTile_Texture;
            _Tile_Enviornment = enviornment;
        }
        public override bool Save_XML(XmlTextWriter textWriter)
        {
            try
            {
                textWriter.WriteStartElement("Game_Object");
                textWriter.WriteAttributeString("Type", this.GetType().AssemblyQualifiedName);
                textWriter.WriteElementString("Left", defaultvertices[0].Position.X.ToString());
                textWriter.WriteElementString("Top", defaultvertices[0].Position.Y.ToString());
                textWriter.WriteElementString("Color0", Colors[0].ToString());
                textWriter.WriteElementString("Color1", Colors[1].ToString());
                textWriter.WriteElementString("Color2", Colors[2].ToString());
                textWriter.WriteElementString("Color3", Colors[3].ToString());
                textWriter.WriteElementString("Tile_Weather", Enum.GetName(typeof(Weather_Type), _Tile_Weather));
                textWriter.WriteElementString("Tile_Enviornment", Enum.GetName(typeof(Enviornment_Type), _Tile_Enviornment));
                textWriter.WriteElementString("Tile_Texture", Enum.GetName(typeof(Tile_Type), _Tile_Texture));
                textWriter.WriteEndElement();
                textWriter.Flush();
            }
            catch
            {
                return false;
            }
            return true;
        }
        #region Game_Object Members
        public override bool dispose()
        {
            return stopDraw();
        }
        #endregion
        #region Draw_Object Members
        public void Draw(GameTime gameTime, GraphicsDevice device)
        {
            //---Set the Texture for this layer
            parent.effect.BaseTexture = parent.Texture_List[groundTexture];
            //---------Begin the drawing passes
            parent.effect.Begin();
            foreach (EffectPass pass in parent.effect.CurrentTechnique.Passes)
            {
                pass.Begin();
                //device.DrawUserPrimitives(PrimitiveType.TriangleStrip, vertices, 0, 2);
				device.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indecies, 0, indecies.Length/3);
                pass.End();
            }
            parent.effect.End();
        }
        public bool startDraw()
        {
            parent.Draw_Functions[0].Add(m_Sort_Delegate);
            return true;
        }
        public bool stopDraw()
        {
            return parent.Draw_Functions[0].Remove(m_Sort_Delegate);
        }
        #endregion
    }
    public enum Weather_Type
    {
        None,
        Drizzle,
        Rain,
        Light_Snow,
        Snow,
        Wind,
        Heavy_Wind,
        Heat_Wave,
        Major_Heat_Wave
    }
    public enum Enviornment_Type
    {
        Normal,
        BrightSun,
        MoonLight,
    }

    public enum Tile_Type
    {
        Grass,
        Sand,
        Snow,
        Swamp,
        Water,
        Dirt
    }
    public class Map_Colors
    {
        static public Color Get_Color(Tile_Type whatType, int index)
        {
            switch (whatType)
            {
                case Tile_Type.Grass:
                    return GrassColorList[index % GrassColorList.Length];
                case Tile_Type.Sand:
                    return SandColorList[index % SandColorList.Length];
                case Tile_Type.Snow:
                    return SnowColorList[index % SnowColorList.Length];
                case Tile_Type.Swamp:
                    return SwampColorList[index % SwampColorList.Length];
                case Tile_Type.Water:
                    return WaterColorList[index % WaterColorList.Length];
                case Tile_Type.Dirt:
                    return DirtColorList[index % DirtColorList.Length];
            }
            return Color.White;
        }
        static public Color[] GrassColorList = {
                                    new Color(0, 150,0),
                                    new Color(5, 150,0),
                                    new Color(15, 150,15),
                                    new Color(0, 155,0),
                                    new Color(5, 155,0),
                                    new Color(15, 155,15),
                                    new Color(0, 145,0),
                                    new Color(5, 145,0),
                                    new Color(15, 145,15)
                                   };
        static public Color[] SandColorList = {
                                    new Color(255,255,255,0),
                                    new Color(255,255,252,0),
                                    new Color(255,255,250,0),
                                    new Color(255,255,248),
                                    new Color(255,255,245,0),
                                    new Color(255,255,243,0)
                                   };
        static public Color[] WaterColorList = {
                                    new Color(252,252,255,0),
                                    new Color(250,250,255,0),
                                    new Color(248,248,255,0),
                                    new Color(245,245,255,0),
                                    new Color(243,243,255,0),
                                    new Color(240,240,255,0),
                                    new Color(237,237,255,0),
                                    new Color(235,235,255,0)
                                   };
        static public Color[] SnowColorList = {
                                    new Color(252,252,252,0),
                                    new Color(250,250,250,0),
                                    new Color(248,248,248,0),
                                    new Color(245,245,245,0),
                                    new Color(243,243,243,0),
                                    new Color(240,240,240,0),
                                    new Color(237,237,237,0),
                                    new Color(235,235,235,0)
                                   };
        static public Color[] DirtColorList = {
                                    new Color(252,252,252,0),
                                    new Color(250,250,250,0),
                                    new Color(248,248,248,0),
                                    new Color(245,245,245,0),
                                    new Color(243,243,243,0),
                                    new Color(240,240,240,0),
                                    new Color(237,237,237,0),
                                    new Color(235,235,235,0)
                                   };
        static public Color[] SwampColorList = {
                                    new Color(255,255,255,0),
                                    new Color(255,255,255,0)
                                   };
    }
}